package com.liankuan.console.controller;

import com.google.common.collect.ImmutableMap;
import com.liankuan.console.annotation.IgnoreSecurity;
import com.liankuan.console.common.BaseRsp;
import com.liankuan.console.common.ResultEnum;
import com.liankuan.console.controller.vo.StrategyListVO;
import com.liankuan.console.controller.vo.StrategyOtherVO.StrategyInfoVO;
import com.liankuan.console.controller.vo.StrategyVO;
import com.liankuan.console.controller.vo.request.*;
import com.liankuan.console.controller.vo.request.Strategy.SaveStrategyIO;
import com.liankuan.console.dto.UserRole;
import com.liankuan.console.service.ServiceImpl.UserRoleServiceImpl;
import com.liankuan.console.service.ServiceImpl.UserStrategyServiceImpl;
import com.liankuan.console.service.StrategyOtherServiceImpl.StrategyOtherServiceImpl;
import com.liankuan.console.service.StrategyService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.List;

@Slf4j
@RestController
@RequestMapping("/strategy")
public class StrategyController {
    private StrategyService strategyService;
    private StrategyOtherServiceImpl strategyOtherService;
    private UserRoleServiceImpl userRoleService;
    private UserStrategyServiceImpl userStrategyService;

    public StrategyController(StrategyService strategyService, StrategyOtherServiceImpl strategyOtherService,
                              UserRoleServiceImpl userRoleService, UserStrategyServiceImpl userStrategyService) {
        this.strategyService = strategyService;
        this.strategyOtherService = strategyOtherService;
        this.userRoleService = userRoleService;
        this.userStrategyService = userStrategyService;
    }

    /**
     * 获取所有的策略列表
     *
     * @return
     */
    @RequestMapping(value = "/lists", method = RequestMethod.GET)
    public BaseRsp listStrategy(@RequestAttribute Integer userId) {
        UserRole userRole = userRoleService.findRoleByUserId(userId);
        List<StrategyListVO> items;

        // TODO （需要完善！）策略和个人绑定之后
        if ("admin".equals(userRole.getRole())) {
            items = strategyService.findAll();
        } else {
            items = strategyService.findAllByUserId(userId);
        }

        return new BaseRsp<>(ImmutableMap.of("list", items, "total", items.size()));
    }

    /**
     * 获取单个策略的详细信息
     *
     * @param id
     * @return
     */
    @RequestMapping(value = "/info", method = RequestMethod.GET)
    public BaseRsp getStrategy(Integer id) {
        StrategyVO vo = strategyService.findOne(id);
        return new BaseRsp<>(vo);
    }


    /**
     * 专门为策略端的接口
     * 根据策略名获取策略信息
     *
     * @return
     */
    // 不需要token就可以访问
    @IgnoreSecurity
    @RequestMapping(value = "/findOne", method = RequestMethod.GET)
    public BaseRsp getStrategyOther(Integer id) {
        StrategyInfoVO vo = strategyOtherService.findOne(id);
        return new BaseRsp<>(vo);
    }

    /**
     * 根据策略ID修改策略的运行状态
     *
     * @param id
     * @return
     */
    @RequestMapping(value = "/updateState", method = RequestMethod.GET)
    public BaseRsp updateStrategyState(Integer id, Integer state) {
        strategyService.updateStrategyState(id, state);
        return new BaseRsp<>(ResultEnum.SUCCESS);
    }


    /**
     * 重启策略
     *
     * @param id
     * @param state
     * @return
     */
    @RequestMapping(value = "/restartState", method = RequestMethod.GET)
    public BaseRsp restartStrategyState(Integer id, Integer state) {
        strategyService.restartStrategyState(id, state);
        return new BaseRsp<>(ResultEnum.SUCCESS);
    }

    /**
     * 保存整个策略信息的提交
     *
     * @param strategyVO
     * @return
     */
    //TODO 暂时没用到
    @RequestMapping("/save")
    public BaseRsp saveStrategy(@RequestBody StrategyVO strategyVO) {
        strategyService.save(strategyVO);
        return new BaseRsp<>(ResultEnum.SUCCESS);
    }

    /**
     * 更新策略对应的交易所信息
     *
     * @param strategyExchangeIO
     * @return
     */
    @RequestMapping(value = "/updateExchange", method = RequestMethod.POST)
    public BaseRsp saveStrategyExchange(@RequestBody StrategyExchangeIO strategyExchangeIO) {
        strategyService.updateExchange(strategyExchangeIO);
        return new BaseRsp<>(ResultEnum.SUCCESS);
    }

    /**
     * 为策略新增一条交易所信息
     *
     * @param strategyExchangeIO
     * @return
     */
    @RequestMapping(value = "/addExchange", method = RequestMethod.POST)
    public BaseRsp addStrategyExchange(@RequestBody StrategyExchangeIO strategyExchangeIO) {
        strategyService.updateExchange(strategyExchangeIO);
        return new BaseRsp<>(ResultEnum.SUCCESS);
    }


    /**
     * 更新策略的基本信息
     *
     * @return
     */
    @RequestMapping(value = "/updateBasic", method = RequestMethod.POST)
    public BaseRsp updateStrategyBasic(@RequestBody StrategyBasicIO strategyBasicIO) {
        strategyService.updateStrategyBasic(strategyBasicIO);
        return new BaseRsp<>(ResultEnum.SUCCESS);
    }


    /**
     * 更新策略的配置信息
     *
     * @param strategyConfigIO
     * @return
     */
    @RequestMapping("/updateConfig")
    public BaseRsp updateStrategyConfig(@RequestBody StrategyConfigIO strategyConfigIO) {
        strategyService.updateStrategyConfig(strategyConfigIO);
        return new BaseRsp<>(ResultEnum.SUCCESS);
    }

    /**
     * 获取策略对应的日志文件信息
     *
     * @param strategyLogIO
     * @return
     */
    @RequestMapping("/logInfo")
    public BaseRsp getStrategyLogInfo(@RequestBody StrategyLogIO strategyLogIO) {
        HashMap map = strategyService.getStrategyLogInfo(strategyLogIO);
        return new BaseRsp<>(map);
    }

    /**
     * 删除策略中某个交易所信息
     *
     * @return
     */
    @RequestMapping("/deleteExchange")
    public BaseRsp deleteExchange(Integer strategyId, Integer exchangeId) {
        strategyService.deleteExchange(strategyId, exchangeId);
        return new BaseRsp<>(ResultEnum.SUCCESS);
    }

    /**
     * 删除策略对应的某条配置参数信息
     *
     * @param strategyConfigIO
     * @return
     */
    @RequestMapping("/deleteConfig")
    public BaseRsp deleteConfig(@RequestBody StrategyConfigIO strategyConfigIO) {
        strategyService.updateStrategyConfig(strategyConfigIO);
        return new BaseRsp<>(ResultEnum.SUCCESS);
    }


    /**
     * 策略新增配置信息
     *
     * @param strategyConfigIO
     * @return
     */
    @RequestMapping("/addConfig")
    public BaseRsp addConfig(@RequestBody StrategyConfigIO strategyConfigIO) {
        strategyService.updateStrategyConfig(strategyConfigIO);
        return new BaseRsp<>(ResultEnum.SUCCESS);
    }

    /**
     * 交易所和人绑定之后
     * 为“【已有】”策略新增交易所时的处理
     *
     * @param strategyId
     * @return
     */
    @RequestMapping("/findAllExchange")
    public BaseRsp getAllExchange(Integer strategyId, @RequestAttribute Integer userId) {
        StrategyAddExchangeVO vo = strategyService.finAllExchange(strategyId, userId);
        return new BaseRsp<>(vo.getTotalExchange());
    }


    /**
     * 存储新增的策略信息
     *
     * @param saveStrategyIO
     * @return
     */
    @RequestMapping("/saveStrategy")
    public BaseRsp saveStrategy(@RequestBody SaveStrategyIO saveStrategyIO, @RequestAttribute Integer userId) {
//        strategyService.saveStrategy(saveStrategyIO);

        //现在的策略是与用户绑定的关系
        strategyService.saveStrategy(saveStrategyIO, userId);
        return new BaseRsp<>(ResultEnum.SUCCESS);
    }

    /**
     * 删除策略信息(人与策略进行了绑定关系)
     *
     * @param id
     * @return
     */
    @RequestMapping("/deleteStrategy")
    public BaseRsp deleteStrategy(Integer id) {
        strategyService.deleteStrategy(id);
        return new BaseRsp<>(ResultEnum.SUCCESS);
    }


    /**
     * 获取策略日志信息最新信息
     *
     * @param strategyId
     * @param lastLineNumber
     * @return
     */
    @RequestMapping("/getNewLogData")
    public BaseRsp getNewLogInfo(Integer strategyId, Integer lastLineNumber) {
        HashMap map = strategyService.getNewLogInfo(strategyId, lastLineNumber);
        return new BaseRsp<>(map);
    }

    /**
     * 获取收益曲线信息
     *
     * @param strategyLogIO
     * @return
     */
    @RequestMapping("/getProfitLog")
    public BaseRsp getProfitLog(@RequestBody StrategyLogIO strategyLogIO) {
        HashMap map = strategyService.getProfitLog(strategyLogIO);
        return new BaseRsp<>(map);
    }

    /**
     * 获取收益曲线最新信息
     *
     * @param strategyId
     * @param lastLineNumber
     * @return
     */
    @RequestMapping("/getNewProfitLog")
    public BaseRsp getNewProfitLog(Integer strategyId, Integer lastLineNumber) {
        HashMap map = strategyService.getNewProfitLog(strategyId, lastLineNumber);
        return new BaseRsp<>(map);
    }

    /**
     * 更新jar包
     *
     * @param strategyId
     * @return
     */
    @RequestMapping("/updateJar")
    public BaseRsp updateJar(Integer strategyId) {
        strategyService.updateJar(strategyId);
        return new BaseRsp<>(ResultEnum.SUCCESS);
    }

    /**
     * 持久化信息
     *
     * @param strategyId
     * @return
     */
    @RequestMapping("/getOrmData")
    public BaseRsp getOrmData(Integer strategyId) {
        StringBuilder ormData = strategyService.getOrmData(strategyId);
        return new BaseRsp<>(ormData);
    }

    /**
     * 判断策略名是否存在
     *
     * @param name
     * @return
     */
    @RequestMapping("/hasStrategyName")
    public BaseRsp hasStrategyName(String name) {
        Boolean isHave = strategyService.hasStrategyName(name);
        return new BaseRsp<>(isHave);
    }


    /**
     * 判断策略名是否存在
     *
     * @param strategyId
     * @return
     */
    @RequestMapping("/getUserStrategyLevel")
    public BaseRsp getUserStrategyLevel(Integer strategyId, @RequestAttribute Integer userId) {
        Integer level = strategyService.getUserStrategyLevel(strategyId,userId);
        return new BaseRsp<>(level);
    }

    /**
     * 下载日志文件
     * @param request
     * @param response
     * @return
     */
    @IgnoreSecurity
    @GetMapping("/download")
    public void downloadFile(HttpServletRequest request, HttpServletResponse response,Integer strategyId) {
            strategyService.downloadFile(request,response,strategyId);
    }


}
